package com.danco.training.zaneuskaya.service.impl;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.danco.training.zaneuskaya.api.AudtorService;
import com.danco.training.zaneuskaya.connection.HibernateSessionUtil;
import com.danco.training.zaneuskaya.connection.dao.AuditorDao;
import com.danco.training.zaneuskaya.connection.dao.impl.AuditorDaoImpl;
import com.danco.training.zaneuskaya.cswworker.CSVReader;
import com.danco.training.zaneuskaya.cswworker.CSVSaver;
import com.danco.training.zaneuskaya.cswworker.Separator;
import com.danco.training.zaneuskaya.domain.Auditor;
import com.danco.training.zaneuskaya.domain.Book;
import com.danco.training.zaneuskaya.domain.Claim;
import com.danco.training.zaneuskaya.domain.Order;

public class AuditorServiceImpl implements AudtorService{
	
	public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
			"dd-MM-yyyy");
	private AuditorDao auditorDao = new AuditorDaoImpl();
	
	private static final Logger logger = Logger
			.getLogger(AuditorServiceImpl.class);


	@Override
	public Auditor getById(Integer id) {
		Session session = null;
		Transaction transaction = null;
		Auditor auditor = null;
		try {
			session = HibernateSessionUtil.getSessionFactory().getCurrentSession();
			transaction = session.beginTransaction();
			auditor = auditorDao.read(session, id);
			transaction.commit();
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
			try{
    			transaction.rollback();
    		}catch(RuntimeException rbe){
    			logger.error("Couldn’t roll back transaction", rbe);
    		}
		}
		return auditor;
	}

	@Override
	public List<Auditor> getList() {
		Transaction transaction = null;
		Session session = null;
		List<Auditor> audits = new ArrayList<Auditor>();
		logger.trace("Audit list");
		try {
			session = HibernateSessionUtil.getSessionFactory().getCurrentSession();
			transaction = session.beginTransaction();
			audits.addAll(auditorDao.readAll(session));
			transaction.commit();
		}catch(RuntimeException e){
    		try{
    			transaction.rollback();
    		}catch(RuntimeException rbe){
    			logger.error("Couldn’t roll back transaction", rbe);
    		}
    		throw e;
    	}
		return audits;
	}

	@Override
	public void addEntity(Auditor e) {
		Transaction transaction = null;
		Session session = HibernateSessionUtil.getSessionFactory().getCurrentSession();

		try {
			transaction = session.beginTransaction();
			auditorDao.create(session, e);
			transaction.commit();

		} catch (HibernateException e1) {
			logger.error(e1.getMessage(), e1);
			try{
				transaction.rollback();
			}catch(RuntimeException rbe){
				logger.error("Couldn’t roll back transaction", rbe);
			}
		}
	}

	@Override
	public void updateEntity(Auditor e) {
		Transaction transaction = null;
		try {
			Session session = HibernateSessionUtil.getSessionFactory().getCurrentSession();
			transaction = session.beginTransaction();

			auditorDao.update(session, e);
			transaction.commit();

		} catch (HibernateException e1) {
			transaction.rollback();

			logger.error(e1.getMessage(), e1);
		}

	
	}

	@Override
	public void removeEntityById(Integer id) {
		Transaction transaction = null;
		try {
			Session session = HibernateSessionUtil.getSessionFactory().getCurrentSession();

			transaction = session.beginTransaction();
			Auditor auditor = auditorDao.read(session, id);
			auditorDao.delete(session, auditor);

			transaction.commit();

		} catch (HibernateException e) {
			transaction.rollback();
			logger.error(e.getMessage(), e);
		}
		
	}

	@Override
	public void saveEntityListToFile(String file) {
		ArrayList<String> res = new ArrayList<String>();
		try {
			Session session = HibernateSessionUtil.getSessionFactory().getCurrentSession();
			for (Auditor audit : auditorDao.readAll(session)) {
				res.add(entityDetails(audit));
			}
		} catch (HibernateException e1) {
			logger.error(e1.getMessage(), e1);
		}
		try {
			CSVSaver.saveListToFile(file, res);
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}
		
	}

	@Override
	public List<Auditor> readEntityList(String file) {
		ArrayList<Auditor> res = new ArrayList<Auditor>();

		Date date = null;

		for (int i = 0; i < CSVReader.readFile(file).length; i++) {
			String audit[] = CSVReader.readFile(file)[i]
					.split(Separator.SEPARATOR.getS());
			try {

				date = DATE_FORMAT.parse(audit[1]);
			} catch (ParseException e) {
				logger.error(e.getMessage(), e);
			}
			Auditor a = new Auditor(Integer.parseInt(audit[0]), date, audit[2], audit[3]);
			res.add(a);

		}
		return res;
	}

	@Override
	public String entityDetails(Auditor e) {
		// not used
		return null;
	}

	@Override
	public List<Auditor> getActionsForPeriod(Date from, Date to) {
		List<Auditor> res = null;
		Session session = null;
		Transaction transaction = null;
		try {
			session = HibernateSessionUtil.getSessionFactory().getCurrentSession();
			transaction = session.beginTransaction();
			res = auditorDao.readAuditsSortedByDate(session, from, to);
			transaction.commit();
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
			transaction.rollback();
		}

		logger.trace("Audits for period are founded");
		return res;
	}

	@Override
	public List<Auditor> getAuditsSortedByDate() {
		List<Auditor> res = null;
		Session session = null;
		Transaction transaction = null;
		try {
			session = HibernateSessionUtil.getSessionFactory().getCurrentSession();
			transaction = session.beginTransaction();
			res = auditorDao.readAuditsSortedByDate(session);
			transaction.commit();
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
			transaction.rollback();
		}

		logger.trace("Audits are sorted");
		return res;	}

}
